<template>
  <div class="m-video" @mouseenter="mouse('enter')" @mouseleave="mouse('leave')">
    <div v-show="originPlay || showPlay" :class="[vplay ? 'hidden' : 'u-play']" class="video-shade">
      <img @click.prevent.once="onPlay" class="img" src="@/assets/images/screen/play_video.png" alt="" />
    </div>
    <transition name="show">
      <div class="videoList" v-show="showVideoList">
        <div
          v-for="(item, index) in videoList"
          :class="{ nowVideo: video_url === item.src }"
          :key="'videoList' + index"
          @click="changeVideo(item)"
        >
          {{ item.title }}
        </div>
      </div>
    </transition>
    <video
      ref="veo"
      class="video"
      :style="`object-fit: ${zoom};`"
      :src="video_url"
      :poster="video_cover"
      :autoplay="autoplay"
      :controls="!originPlay && controls"
      :loop="loop"
      :muted="autoplay || muted"
      :preload="preload"
      @click.prevent.once="onPlay"
    >
      您的浏览器不支持video标签。
    </video>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, nextTick } from "vue";

interface videoItem {
  title: string;
  src: string;
  poster: string;
}

interface Props {
  videoUrl: string; // 视频文件url，必传，支持网络地址 https 和相对地址 require('@/assets/files/Bao.mp4')
  videoCover?: string; // 视频封面url，支持网络地址 https 和相对地址 require('@/assets/images/Bao.jpg')
  width?: number; // 视频播放器宽度
  height?: number; // 视频播放器高度
  autoplay?: boolean; // 视频就绪后是否马上播放
  controls?: boolean; // 是否向用户显示控件，比如进度条，全屏
  loop?: boolean; // 视频播放完成后，是否循环播放
  muted?: boolean; // 是否静音
  preload?: string; // 是否在页面加载后载入视频，如果设置了autoplay属性，则preload将被忽略；
  showPlay?: boolean; // 播放暂停时是否显示播放器中间的暂停图标
  playWidth?: number; // 中间播放暂停按钮的边长
  zoom?: string; // video的poster默认图片和视频内容缩放规则
  isClick?: boolean; // 是否可以点击暂停
  videoList?: videoItem[]; //视频列表
}

const props = withDefaults(defineProps<Props>(), {
  videoUrl: "https://www.runoob.com/try/demo_source/movie.mp4",
  videoCover: "",
  width: 800,
  height: 450,
  /*
    autoplay：由于目前在最新版的Chrome浏览器（以及所有以Chromium为内核的浏览器）中，
    已不再允许自动播放音频和视频。就算你为video或audio标签设置了autoplay
    属性也一样不能自动播放！
    本组件解决方法：设置视频 autoplay 时，自动将视频设置为静音 muted: true 即可实现自
    动播放，然后用户可以使用控制栏开启声音，类似某宝商品自动播放的宣传视频逻辑
  */
  autoplay: false,
  controls: true,
  loop: false,
  muted: false,
  /*
    preload可选属性：
    auto:一旦页面加载，则开始加载视频;
    metadata:当页面加载后仅加载视频的元数据
    none:页面加载后不应加载视频
  */
  preload: "auto",
  showPlay: true,
  playWidth: 96,
  /*
    zoom可选属性：
    none:(默认)保存原有内容，不进行缩放;
    fill:不保持原有比例，内容拉伸填充整个内容容器;
    contain:保存原有比例，内容以包含方式缩放;
    cover:保存原有比例，内容以覆盖方式缩放
  */
  zoom: "none",
  isClick: true,
  videoList: () => []
});

const video_url = ref(props.videoUrl);
const video_cover = ref(props.videoCover);

if (props.videoList.length) {
  video_cover.value = props.videoList.filter(item => item.src === video_url.value)[0].poster;
}

const originPlay = ref(true);
const vplay = ref(false);
const isShow = ref(true);
// 为模板引用标注类型
// 或 const veo = ref()
const veo = ref<HTMLVideoElement | null>(null); // 声明一个同名的模板引用

const showVideoList = ref(false);

const mouse = (type: string) => {
  showVideoList.value = type === "enter";
};

const changeVideo = (item: videoItem) => {
  if (item.src) {
    video_url.value = item.src;
    if (item.poster) {
      video_cover.value = item.poster;
    }
  }
};

function onPlay() {
  if (!props.isClick) return;
  if (props.autoplay) {
    veo.value?.pause();
  } else {
    vplay.value = true;
    originPlay.value = false;
    veo.value?.play();
  }
  isShow.value = !isShow.value;
}

function onPause() {
  vplay.value = false;
}

function onPlaying() {
  vplay.value = true;
}

onMounted(() => {
  if (props.showPlay) {
    veo.value?.addEventListener("pause", onPause);
    veo.value?.addEventListener("playing", onPlaying);
  }
  if (props.autoplay) {
    vplay.value = true;
    originPlay.value = false;
    nextTick(() => {
      if (!props.muted) {
        // @ts-ignore
        veo.value.muted = false;
        veo.value?.play();
      }
    });
  }
  // 自定义设置播放速度
  // this.$refs.veo.playbackRate = 2
});
onUnmounted(() => {
  veo.value?.removeEventListener("pause", onPause);
  veo.value?.removeEventListener("playing", onPlaying);
});
</script>

<style scoped lang="scss">
.m-video {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  //   display: inline-block;
  position: relative;
  cursor: pointer;

  .video-shade {
    width: 100%;
    height: 100%;
    position: absolute;
    background: #111111;
    opacity: 0;
  }

  .video {
    width: 100%;
    height: 100%;
  }

  &:hover {
    .u-play {
      opacity: 0.9;
    }
  }

  .u-play {
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
    fill: none;
    color: #fff;
    pointer-events: none;
    opacity: 0.7;
    transition: opacity 0.3s;
  }

  .svgs {
    width: 40%;
    height: 40%;
  }

  .hidden {
    display: none;
  }

  .img {
    width: 4.47vw;
    height: 4.47vw;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translateX(-50%) translateY(-50%);
    // z-index: 99;
  }

  .videoList {
    position: absolute;
    z-index: 100;
    top: 0;
    left: 0;
    width: 100%;
    display: flex;
    justify-content: space-between;
    text-align: center;

    & > div {
      flex: 1;
      padding: 1.5vh 0;
      background: rgba(0, 32, 96, 0.6);
      color: #a6c7ff;
      font-size: 0.84vw;
      position: relative;
    }

    & > div::after {
      position: absolute;
      display: inline-block;
      content: " ";
      width: 0.11vw;
      height: 2.5vh;
      top: 50%;
      right: 0;
      transform: translateY(-50%);
      background: linear-gradient(0deg, rgba(24, 36, 80, 0) 0%, rgba(219, 227, 255, 0.98) 49%, rgba(24, 36, 80, 0) 100%);
    }

    & > div:last-child::after {
      display: none;
    }

    & > div:hover {
      color: #ffffff;
      background: linear-gradient(0deg, rgba(111, 159, 255, 0.6) 0%, rgba(9, 24, 79, 0.6) 35%);
    }

    .nowVideo {
      color: #ffffff;
      background: linear-gradient(0deg, rgba(111, 159, 255, 0.6) 0%, rgba(9, 24, 79, 0.6) 35%);
    }
  }

  .show-enter-active,
  .show-leave-active {
    transition: opacity 0.5s ease;
  }

  .show-enter-from,
  .show-leave-to {
    opacity: 0;
  }
}
</style>
